//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.tsfyun.scm.util;

import cn.hutool.core.collection.CollectionUtil;
import com.tsfyun.common.base.util.StringUtils;
import tk.mybatis.mapper.entity.SqlsCriteria;
import tk.mybatis.mapper.util.Sqls.Criteria;
import tk.mybatis.mapper.util.Sqls.Criterion;
import tk.mybatis.mapper.weekend.Fn;
import tk.mybatis.mapper.weekend.reflection.Reflections;

/**
 * 直接拷贝过来的，主要修正某些查询参数不为空则不需要带入到查询中去
 * @param <T>
 */
public class TsfWeekendSqls<T> implements SqlsCriteria {
    private Criteria criteria = new Criteria();

    private TsfWeekendSqls() {
    }

    public static <T> TsfWeekendSqls<T> custom() {
        return new TsfWeekendSqls();
    }

    public TsfWeekendSqls<T> andIsNull(String property) {
        this.criteria.getCriterions().add(new Criterion(property, "is null", "and"));
        return this;
    }

    public TsfWeekendSqls<T> andIsNull(Fn<T, Object> fn) {
        return this.andIsNull(Reflections.fnToFieldName(fn));
    }

    public TsfWeekendSqls<T> andIsNotNull(String property) {
        this.criteria.getCriterions().add(new Criterion(property, "is not null", "and"));
        return this;
    }

    public TsfWeekendSqls<T> andIsNotNull(Fn<T, Object> fn) {
        return this.andIsNotNull(Reflections.fnToFieldName(fn));
    }

    //当需要校验空值时且不为空就加入等于条件
    public TsfWeekendSqls<T> andEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "=", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "=", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andEqualTo(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andNotEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<>", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<>", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andNotEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andNotEqualTo(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andGreaterThan(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, ">", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, ">", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andGreaterThan(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andGreaterThan(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andGreaterThanOrEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, ">=", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, ">=", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andGreaterThanOrEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andGreaterThanOrEqualTo(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andLessThan(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andLessThan(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andLessThan(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andLessThanOrEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<=", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<=", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andLessThanOrEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, Object value) {
        return this.andLessThanOrEqualTo(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andIn(boolean notEmptyCheck,String property, Iterable values) {
        if(notEmptyCheck) {
            if(null != values && CollectionUtil.isNotEmpty(values)) {
                this.criteria.getCriterions().add(new Criterion(property, values, "in", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, values, "in", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andIn(boolean notEmptyCheck,Fn<T, Object> fn, Iterable values) {
        return this.andIn(notEmptyCheck,Reflections.fnToFieldName(fn), values);
    }

    public TsfWeekendSqls<T> andNotIn(boolean notEmptyCheck,String property, Iterable values) {
        if(notEmptyCheck) {
            if(null != values && CollectionUtil.isNotEmpty(values)) {
                this.criteria.getCriterions().add(new Criterion(property, values, "not in", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, values, "not in", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andNotIn(boolean notEmptyCheck,Fn<T, Object> fn, Iterable values) {
        return this.andNotIn(notEmptyCheck,Reflections.fnToFieldName(fn), values);
    }

    public TsfWeekendSqls<T> andBetween(String property, Object value1, Object value2) {
        this.criteria.getCriterions().add(new Criterion(property, value1, value2, "between", "and"));
        return this;
    }

    public TsfWeekendSqls<T> andBetween(Fn<T, Object> fn, Object value1, Object value2) {
        return this.andBetween(Reflections.fnToFieldName(fn), value1, value2);
    }

    public TsfWeekendSqls<T> andNotBetween(String property, Object value1, Object value2) {
        this.criteria.getCriterions().add(new Criterion(property, value1, value2, "not between", "and"));
        return this;
    }

    public TsfWeekendSqls<T> andNotBetween(Fn<T, Object> fn, Object value1, Object value2) {
        return this.andNotBetween(Reflections.fnToFieldName(fn), value1, value2);
    }

    public TsfWeekendSqls<T> andLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value + "%", "like", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%"+value+"%", "like", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.andLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andLeftLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value, "like", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%"+value, "like", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andLeftLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.andLeftLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andRightLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value + "%", "like", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value+"%", "like", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andRightLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.andRightLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> andNotLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "not like", "and"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "not like", "and"));
        }
        return this;
    }

    public TsfWeekendSqls<T> andNotLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.andNotLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> orIsNull(String property) {
        this.criteria.getCriterions().add(new Criterion(property, "is null", "or"));
        return this;
    }

    public TsfWeekendSqls<T> orIsNull(Fn<T, Object> fn) {
        return this.orIsNull(Reflections.fnToFieldName(fn));
    }

    public TsfWeekendSqls<T> orIsNotNull(String property) {
        this.criteria.getCriterions().add(new Criterion(property, "is not null", "or"));
        return this;
    }

    public TsfWeekendSqls<T> orIsNotNull(Fn<T, Object> fn) {
        return this.orIsNotNull(Reflections.fnToFieldName(fn));
    }

    public TsfWeekendSqls<T> orEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "=", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "=", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orEqualTo(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orNotEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<>", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<>", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orNotEqualTo(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orGreaterThan(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, ">", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, ">", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orGreaterThan(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orGreaterThan(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orGreaterThanOrEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, ">=", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, ">=", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orGreaterThanOrEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orGreaterThanOrEqualTo(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orLessThan(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orLessThan(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orLessThan(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orLessThanOrEqualTo(boolean notEmptyCheck,String property, Object value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value, "<=", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value, "<=", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orLessThanOrEqualTo(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orLessThanOrEqualTo(notEmptyCheck,(String)Reflections.fnToFieldName(fn), (Object)value);
    }

    public TsfWeekendSqls<T> orIn(boolean notEmptyCheck,String property, Iterable values) {
        if(notEmptyCheck) {
            if(CollectionUtil.isNotEmpty(values)) {
                this.criteria.getCriterions().add(new Criterion(property, values, "in", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, values, "in", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orIn(boolean notEmptyCheck,Fn<T, Object> fn, Iterable values) {
        return this.orIn(notEmptyCheck,Reflections.fnToFieldName(fn), values);
    }

    public TsfWeekendSqls<T> orNotIn(boolean notEmptyCheck,String property, Iterable values) {
        if(notEmptyCheck) {
            if(CollectionUtil.isNotEmpty(values)) {
                this.criteria.getCriterions().add(new Criterion(property, values, "not in", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, values, "not in", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotIn(boolean notEmptyCheck,Fn<T, Object> fn, Iterable values) {
        return this.orNotIn(notEmptyCheck,Reflections.fnToFieldName(fn), values);
    }

    public TsfWeekendSqls<T> orBetween(boolean notEmptyCheck,String property, Object value1, Object value2) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value1) && StringUtils.isNotEmpty(value2)) {
                this.criteria.getCriterions().add(new Criterion(property, value1, value2, "between", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value1, value2, "between", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orBetween(boolean notEmptyCheck,Fn<T, Object> fn, Object value1, Object value2) {
        return this.orBetween(notEmptyCheck,Reflections.fnToFieldName(fn), value1, value2);
    }

    public TsfWeekendSqls<T> orNotBetween(boolean notEmptyCheck,String property, Object value1, Object value2) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value1) && StringUtils.isNotEmpty(value2)) {
                this.criteria.getCriterions().add(new Criterion(property, value1, value2, "not between", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value1, value2, "not between", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotBetween(boolean notEmptyCheck,Fn<T, Object> fn, Object value1, Object value2) {
        return this.orNotBetween(notEmptyCheck,Reflections.fnToFieldName(fn), value1, value2);
    }

    public TsfWeekendSqls<T> orLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value + "%", "like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%" + value + "%", "like", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }


    public TsfWeekendSqls<T> orLeftLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value, "like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%" + value, "like", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orLeftLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orLeftLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> orRightLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orLeftLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }

    public TsfWeekendSqls<T> orRightLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value + "%", "like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value + "%", "like", "or"));
        }
        return this;
    }


    public TsfWeekendSqls<T> orNotLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value + "%", "not like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%" + value + "%", "not like", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orNotLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }


    public TsfWeekendSqls<T> orNotLeftLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, "%" + value, "not like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, "%" + value, "not like", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotLeftLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orNotLeftLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }



    public TsfWeekendSqls<T> orNotRightLike(boolean notEmptyCheck,String property, String value) {
        if(notEmptyCheck) {
            if(StringUtils.isNotEmpty(value)) {
                this.criteria.getCriterions().add(new Criterion(property, value + "%", "not like", "or"));
            }
        } else {
            this.criteria.getCriterions().add(new Criterion(property, value + "%", "not like", "or"));
        }
        return this;
    }

    public TsfWeekendSqls<T> orNotRightLike(boolean notEmptyCheck,Fn<T, Object> fn, String value) {
        return this.orNotRightLike(notEmptyCheck,Reflections.fnToFieldName(fn), value);
    }


    public Criteria getCriteria() {
        return this.criteria;
    }
}
